//
//  main.m
//  07-内存管理
//
//  Created by Snow on 16/7/12.
//  Copyright © 2016年 Snow. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Man.h"

int main(int argc, const char * argv[]) {
   //内存问题:
    // 一.内存溢出
    //    内存过多 导致溢出 , 产生crash
    
    // 二.野指针(过度释放)
    //    指针指向未知区域, 指向一块被释放的内存
    
    //内存管理方式
    // 1.垃圾回收机制: 只有Mac上有
    // 2.MRC:手动管理引用计数
    // 3.ARC:自动管理用用计数(现在常用)
    // 注意: ARC基于MRC进行管理, 系统帮程序员添加了内存管理内容
    // retain.alloc.copy需要进行内存管理
//    NSObject *obj = [[NSObject alloc] init];
//    [obj retain];
//    [obj release];
//    [obj release];
    
    //内存管理: 引用计数(计数器)
    // 有 retain.alloc.copy 会对引用计数 + 1
    // 有 release autorelease 会对引用计数 - 1
    // 当对象的计数器为0的时候, 系统会调用对应的dealloc方法
   // 注意: 内存管理, 对对象操作完成后,在进行释放
    
    //MRC
    Man *man = [[Man alloc] init];
    NSLog(@"%ld", man.retainCount);
    [man retain];
    [man release];
    NSLog(@"%ld", man.retainCount);
    //集合类型, 会对对象进行引用计数
    // addObject , 对对象进行引用计数 + 1
    // removeObject 对 对象类型进行引用计数 - 1
    NSMutableArray *array = [NSMutableArray arrayWithObjects:man, nil];
    NSLog(@"向数组中添加后的引用计数:%ld", man.retainCount);
    [array removeAllObjects];
    NSLog(@"从数组中移除后的引用计数 %ld", man.retainCount);
    
    //2.ARC
    // strong(强引用 , 引用计数 + 1)
    // weak (应用于(NSObject子类)弱引用, 对象被释放是,会自动置空)
    // retian(强引用, 引用计数 + 1)
    // assign(应用于简单的数据类型,不会产生引用计数);
    // copy(拷贝, 把对象拷贝一份, 原来的引用计数不变, 新的加1)
    
    //3.协议的步骤
    // 声明协议
    // 签订协议
    // 实现协议方法
    
    //如果想实现对对象的拷贝
    // 1.签订学医NSCoping
    // 2.实现协议方法:copyWithZone;
    Man *woman = [man copy];
    NSLog(@"%@", woman);
    
    //拷贝分组
    // 2.浅拷贝
    // 3.深拷贝
   // 对象类型且遵守拷贝协议的才能使用copy
    
    //KVC
    //间接访问成员变量的方法
    //只要是NSObject子类就有这些方法
    //valueForKey
    //valueForKeyPath
    //setValue:forKye
    // setValue:forKeyPath
//    [NSObject new] setValue:<#(nullable id)#> forKey:<#(nonnull NSString *)#>
    
    woman.name = @"hanxu";
    woman.seual = @"man";
    
    id name = [woman valueForKey:@"name"];
    NSLog(@"%@", name);
    [woman setValue:@"xukang" forKey:@"name"];
    NSLog(@"--%@", woman.name);
    
    Man *gayMan = [[Man alloc] init];
    gayMan.gayBoy = woman;
    
    id boyName = [gayMan valueForKeyPath:@"gayBoy.name"];
    NSLog(@"%@", boyName);
    
    [gayMan release];
    [gayMan setValue:@"lisi" forKeyPath:@"gayBoy.name"];
    NSLog(@"%@", gayMan.gayBoy.name);
    
//    NSDictionary *dic = [NSDictionary dictionary];
//    [dic setValue:@"zhangsan" forKey:@"name"];
//    NSLog(@"%@", dic);//字典不能够KVC
    
    NSMutableDictionary *dic1 = [NSMutableDictionary dictionary];
    [dic1 setValue:@"zhangsan" forKey:@"name"];
    NSLog(@"%@", dic1);
    
    
    NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:@"123", @"mId", @"dvsdg", @"mDescription", nil];
    Man *dicMan = [[Man alloc] init];
    [dicMan setValue:@"33" forKey:@"mId"];
    NSLog(@"%@", dicMan.mId);
    
    //加在build Phases - com...文件下
    //如果在ARC工程下使用MRC文件
    //-fno-objc-arc
    //如果在MRC工程下使用ARC文件
    // -fobjc-arc
    return 0;
}
